/**
 * JAVACC DEMO 1.0
 */
package com.apache.portal.common.template;

import com.apache.api.vo.ResultEntity;
import com.apache.portal.common.util.PortalPubFactory;
import com.apache.rpc.common.LoadRpcService;
import com.apache.tools.ConfigUtil;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description: 生成sql
 *
 * @author dyhou 创建时间：2016-9-29
 */
public class CreateTableSql {

    private static CreateTableSql instance;

    private CreateTableSql() {
        //
    }

    public static synchronized CreateTableSql instance() {
        if (null == instance) {
            instance = new CreateTableSql();
        }
        return instance;
    }

    /**
     * description:  生成数据库创建脚本
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public String createTable(Map<String, String> params) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.putAll(params);
        Map<String, Object> paramVo = new HashMap<String, Object>();
        //paramVo.put("sortInfo.w_sortId", param.get("ids"));
        paramVo.put("modelTypes", "s_sortInfo");
        List list = (List) init(paramVo);
        if (ToolsUtil.isEmpty(list)) {
            return "";
        }
        int count = list.size();
        StringBuffer sb = new StringBuffer();
        String databaseType = StrUtil.doNull(params.get("databaseType"), "oracle");
        for (int i = 0; i < count; i++) {
            Map sortInfo = (Map) list.get(i);
            paramVo.put("modelTypes", "s_metadata");
            paramVo.put("metadata.w_sortId", sortInfo.get("sortId"));
            List mlist = (List) init(paramVo);
            String sql = "";
            if ("oracle".equalsIgnoreCase(databaseType)) {
                sql = getTableOracleSql(sortInfo, params, mlist);
            } else if ("mySql".equalsIgnoreCase(databaseType)) {
                sql = getTableMysqlSql(sortInfo, params, mlist);
            } else if ("sqlserver".equalsIgnoreCase(databaseType)) {
                sql = getTableSqlServerSql(sortInfo, params, mlist);
            }
            sb.append(sql);
        }
        return sb.toString();
    }

    public Object init(Map map) {
        map.put("resultType", "objInfo");
        map.put("resultObjType", "list");
        map.put("sysPass", ConfigUtil.getInstance().interfacePass());
        String dataSource = String.valueOf(map.get("datasource"));
        String beanId = PortalPubFactory.getInstance().getBeanId(dataSource);
        ResultEntity entity = LoadRpcService.service().doServiceClient(beanId, "dymicSql", map,
                PortalPubFactory.getInstance().getRpcInfo("ius"));
        return entity.getEntity();
    }

    public Object initCount(Map map) {
        map.put("resultType", "objInfo");
        map.put("resultObjType", "count");
        map.put("sysPass", ConfigUtil.getInstance().interfacePass());
        String dataSource = String.valueOf(map.get("datasource"));
        String beanId = PortalPubFactory.getInstance().getBeanId(dataSource);
        ResultEntity entity = LoadRpcService.service().doServiceClient(beanId, "dymicSql", map,
                PortalPubFactory.getInstance().getRpcInfo("ius"));
        return entity.getEntity();
    }

    private String getTableOracleSql(Map info, Map param, List<Map> list) {
        StringBuffer sb = new StringBuffer();
        if (ToolsUtil.isEmpty(list)) {
            return "";
        }
        String pk = "";
        sb.append("create table " + String.valueOf(info.get("infoTableName")) + "( <br>");
        for (Map mp : list) {
            sb.append(String.valueOf(mp.get("dataShortName")) + " ");
            String dataType = String.valueOf(mp.get("dataType"));
            String dataLength = String.valueOf(mp.get("dataLength"));
            String dataRestrict = String.valueOf(mp.get("dataRestrict"));
            if ("1".equals(dataType) || "2".equals(dataType)) {
                sb.append(" number(" + dataLength + ") ");
            } else if ("3".equals(dataType)) {
                sb.append(" number(" + dataLength + ",6) ");
            } else if ("4".equals(dataType)) {
                sb.append(" char(" + dataLength + ") ");
            } else if ("6".equals(dataType)) {
                sb.append(" date ");
            } else if ("7".equals(dataType)) {
                sb.append(" clob ");
            } else {
                sb.append(" varchar2(" + dataLength + ") ");
            }
            if ("1".equals(dataRestrict) || "2".equals(dataRestrict)) {
                sb.append(" not null ");
                if ("1".equals(dataRestrict)) {
                    pk = String.valueOf(mp.get("dataShortName"));
                }
            }
            sb.append(", <br>");
        }
        if (ToolsUtil.isNotNull(pk))
            sb.append(" primary key(" + pk + ") <br>");
        sb.append("); <br>");
        return sb.toString();
    }

    private String getTableMysqlSql(Map info, Map param, List<Map> list) {
        StringBuffer sql = new StringBuffer();
        if (ToolsUtil.isEmpty(list)) {
            return "";
        }
        String pk = "";
        sql.append("create table " + String.valueOf(info.get("infoTableName")) + "( <br>");
        for (Map mp : list) {
            String dataType = String.valueOf(mp.get("dataType"));
            String dataLength = String.valueOf(mp.get("dataLength"));
            String dataRestrict = String.valueOf(mp.get("dataRestrict"));
            sql.append(" " + String.valueOf(mp.get("dataShortName")) + " ");
            if ("1".equals(dataType)) {
                sql.append(" int ");
            } else if ("2".equals(dataType)) {
                sql.append(" bigint ");
            } else if ("3".equals(dataType)) {
                sql.append(" float");
            } else if ("4".equals(dataType)) {
                sql.append(" char(" + dataLength + ") ");
            } else if ("6".equals(dataType)) {
                sql.append(" datetime ");
            } else if ("7".equals(dataType)) {
                sql.append(" text ");
            } else if ("8".equals(dataType)) {
                sql.append(" decimal(" + dataLength + ") ");
            }  else {
                sql.append(" varchar(" + dataLength + ") ");
            }
            if ("1".equals(dataRestrict) || "2".equals(dataRestrict)) {
                sql.append(" not null ");
                if ("1".equals(dataRestrict)) {
                    pk = String.valueOf(mp.get("dataShortName"));
                }
            }
            sql.append(", <br>");
        }
        if (ToolsUtil.isNotNull(pk))
            sql.append(" primary key(" + pk + ") <br>");
        sql.append("); <br>");
        return sql.toString();
    }

    private String getTableSqlServerSql(Map info, Map param, List<Map> list) {
        StringBuffer sql = new StringBuffer();
        if (ToolsUtil.isEmpty(list)) {
            return "";
        }
        String pk = "";
        sql.append("create table " + String.valueOf(info.get("infoTableName")) + "( <br>");
        for (Map mp : list) {
            String dataType = String.valueOf(mp.get("dataType"));
            String dataLength = String.valueOf(mp.get("dataLength"));
            String dataRestrict = String.valueOf(mp.get("dataRestrict"));
            sql.append(" " + String.valueOf(mp.get("dataShortName")) + " ");
            if ("1".equals(dataType)) {
                sql.append(" int ");
            } else if ("2".equals(dataType)) {
                sql.append(" bigint ");
            } else if ("3".equals(dataType)) {
                sql.append(" float");
            } else if ("4".equals(dataType)) {
                sql.append(" char(" + dataLength + ") ");
            } else if ("6".equals(dataType)) {
                sql.append(" datetime ");
            } else if ("7".equals(dataType)) {
                sql.append(" text ");
            } else if("8".equals(dataType)){
                sql.append(" decimal(" + dataLength + ") ");
            } else {
                sql.append(" varchar(" + dataLength + ") ");
            }
            if ("1".equals(dataRestrict) || "2".equals(dataRestrict)) {
                sql.append(" not null ");
                if ("1".equals(dataRestrict)) {
                    pk = String.valueOf(mp.get("dataShortName"));
                }
            }
            sql.append(", <br>");
        }
        if (ToolsUtil.isNotNull(pk))
            sql.append(" primary key(" + pk + ") <br>");
        sql.append("); <br>");
        return sql.toString();
    }
}
